<?php defined('SYSPATH') or die('No direct script access.');
set_time_limit(0);

class Model_ProductParser_Mixmarket extends Model_ProductParser_Abstract
{ 
    protected $filename = null;         // Название файла
    protected $handler = null;          // Дескриптор файла
    protected $charset = null;          // Кодировка входного файла
    
    /**
    * Парсим товары магазина
    * 
    * @param Model_Shop $shop
    */
    public function parse($filename)
    {        
        $this->filename = APPPATH . '../data/feeds/mixmarket/' . $filename . '.xml';
        
        $this->_open_file();   
        $this->_detect_charset();
        
        while ($shop_data = $this->_get_shop()) {
            $shop_id   = $this->_get_shop_id($shop_data);
            $shop_name = $this->_get_shop_name($shop_data);
            $shop_url  = $this->_get_shop_url($shop_data);
            
            try { 
                //echo $shop_id.'<br>'.$shop_name.'<br>'.$shop_url.'<br>';           
                DB::insert('mixmarket_shops', array('id', 'name', 'url'))
                        ->values(array($shop_id, $shop_name, $shop_url))->execute();
            } catch (Database_Exception $e) {
                if (strstr($e->getMessage(), 'Duplicate entry') !== false) {
                    //continue;
                } else {
                    die($e->getMessage());
                }
            }
            
            while ($category_data = $this->_get_category($shop_data)) {
                $category_id = $this->_get_category_id($category_data);
                $category_name = $this->_get_category_name($category_data);
                $parent_id   = $this->_get_category_parent_id($category_data);
                
                try {
                    //echo $category_id.' - '.$name.' - '.$parent_id.'<br />';
                    DB::insert('mixmarket_categories', array('id', 'parent_id', 'name'))
                        ->values(array($category_id, $parent_id, $category_name))->execute();
                } catch (Database_Exception $e) {
                    if (strstr($e->getMessage(), 'Duplicate entry') !== false) {
                        //continue;
                    } else {
                        die($e->getMessage());
                    }
                }
            }
            
            // Добавляем товары
            while ($product_data = $this->_get_product()) {
                $product_id = $this->_get_product_id($product_data);
                $category_id = $this->_get_product_category_id($product_data);
                $url        = $this->_get_product_url($product_data);
                
                $vendor_id  = $this->_get_product_vendor_id($product_data);
                $vendor     = $this->_get_product_vendor($product_data);
                $model      = $this->_get_product_model($product_data);
                
                $name       = $this->_get_product_name($product_data);
                $picture    = $this->_get_product_picture($product_data);
                
                $price      = $this->_get_product_price($product_data);
                $currency   = $this->_get_product_currency($product_data);
                $type_prefix = $this->_get_product_type_prefix($product_data);
                $description = $this->_get_product_description($product_data);
                
                
                try {
                    /*echo "id - $product_id<br />";
                    echo "category - $category_id<br />";
                    echo "url - $url<br />";
                    echo "vendor_id - $vendor_id<br />";
                    echo "vendor - $vendor<br />";
                    echo "model - $model<br />";
                    echo "name - $name<br />";
                    echo "picture - $picture<br />";
                    echo "price - $price<br />";
                    echo "currency - $currency<br />";
                    echo "type_prefix - $type_prefix<br />";
                    echo "description - $description<br /><br />";*/ 
                    ORM::factory('product_mixmarket')->add_product($product_id, $shop_id, $category_id, $url, $name, $picture, $price,
                            $currency, $type_prefix, $vendor_id, $vendor, $model, $description);
                } catch (Database_Exception $e) {
                    if (strstr($e->getMessage(), 'Duplicate entry') !== false) {
                        continue;
                    }
                    die($e->getMessage());
                }
            }       
        }
        echo 'ok';
        $this->_close_file();      
    }                
    
    protected function _get_product_id(&$product_data)
    {
        $product_id = $this->_cut_str(' id="', '"', $product_data); 
        return $product_id; 
    }
    
    protected function _get_product_category_id(&$product_data)
    {
        $category_id = $this->_cut_str('<categoryId>', '</categoryId>', $product_data); 
        return $category_id;  
    }
    
    protected function _get_product_url(&$product_data)
    {
        $url = $this->_cut_str('<url>', '</url>', $product_data);
        return $url;
    }
    
    protected function _get_product_name(&$product_data)
    {
        $name = $this->_cut_str('<name>', '</name>', $product_data);
        if ($name = trim($name)) {
            return $this->_cut_quotes($name);    
        }
        return null;  
    }
    
    protected function _get_product_picture(&$product_data)
    {
        $picture = $this->_cut_str('<picture', '</picture>', $product_data);
        if ($picture) {
            $picture = '<picture'.$picture.'</picture>';
            return strip_tags($picture);
        }
        return null;  
    }
    
    protected function _get_product_vendor_id(&$product_data)
    {
        $id = $this->_cut_str('dor id="', '"', $product_data);
        if ($id) {
            return $id;
        }
        return 0;
    }
    
    protected function _get_product_vendor(&$product_data)
    {
        $vendor = $this->_cut_str('<ven>', '</vendor>', $product_data);
        if ($vendor) {
            return $this->_cut_quotes($vendor);    
        }
        return null;
    }
    
    protected function _get_product_model(&$product_data)
    {
        $model  = $this->_cut_str('<model>', '</model>', $product_data);
        if ($model) {
            return $this->_cut_quotes($model);    
        }
        return null;
    }
    
    protected function _get_product_price(&$product_data)
    {
        $price = $this->_cut_str('<price>', '</price>', $product_data);
        if ($price) {
            return $price;
        }
        return 0;    
    }
    
    protected function _get_product_currency(&$product_data)
    {
        $currency = $this->_cut_str('<currencyId>', '</currencyId>', $product_data);
        if ($currency) {
            return $currency;
        }
        return null;    
    }
    
    protected function _get_product_type_prefix(&$product_data)
    {
        $prefix = $this->_cut_str('<typePrefix>', '</typePrefix>', $product_data);
        if ($prefix) {
            return $prefix;
        }
        return null;    
    }
               
    protected function _get_product_description(&$product_data)
    {
        $description = $this->_cut_str('<description>', '</description>', $product_data);
        if ($description) {
            return $description;
        }
        return null;   
    }
    
    protected function _get_category_id(&$category_data)
    {
        $category_id = $this->_cut_str('id="', '"', $category_data);
        return $category_id;  
    }
    
    protected function _get_category_name(&$category_data)
    {
        $name = $this->_cut_str('>', '<', $category_data);
        return $this->_cut_quotes($name);  
    }
    
    protected function _get_category_parent_id(&$category_data)
    {
        $parent_id = $this->_cut_str('parentId="', '"', $category_data);
        return $parent_id;  
    }
    
    protected function _get_shop_id(&$shop_data)
    {
        $shop_id = $this->_cut_str(' id="', '"', $shop_data); 
        return $shop_id;   
    }
    
    protected function _get_shop_name($shop_data)
    {
        $name = $this->_cut_str('<name>', '</name>', $shop_data); 
        return $name;     
    }
    
    protected function _get_shop_url(&$shop_data)
    {
        if ($name = $this->_cut_str('ref><name>', '</name></url', $shop_data)) {
            return str_replace('www.', '', $name);    
        }   
        return null; 
    }
    
    protected function _open_file()
    {
        $result = $this->handler = fopen($this->filename, 'r+'); 
        if (!$result) {
            throw new Model_Exception('Не удалось открыть файл');
        }
        return $result; 
    }
    
    protected function _detect_charset()
    {
        $str = fgets($this->handler);
        $charset = $this->_cut_str(' encoding="', '"', $str);
        
        if ($charset) {
            $this->charset = mb_strtolower($charset);
        } else {
            $this->charset = 'utf-8';
        }
    }
    
    protected function _encode($str)
    {
        if ($this->charset == 'utf-8') {
            return $str;
        }
        
        return iconv($this->charset, 'utf-8', $str);
    }
    
    protected function _get_product()
    {
        $data = null;
        while($str = fgets($this->handler)) {              
            if (strstr($str, '<offer') !== false) {
                $data = $str;
                
                $str = fgets($this->handler);
                while (strstr($str, '</offer>') === false) {
                    $data .= $str;
                    $str   = fgets($this->handler);
                }
                if (strstr($str, '</offers>') !== false) {
                    return false;    
                }
                fseek($this->handler, -mb_strlen($str), SEEK_CUR);
                
                break;
            }
        }     
        return $this->_encode($data);
    }
    
    protected function _get_category(&$shop_data)
    {
        if ($category = $this->_cut_str('<category ', '/category>', $shop_data)) {
            return $category;    
        }   
        return null; 
    }
    
    protected function _get_shop()
    {
        $data = null;
        while($str = fgets($this->handler)) {                 
            if (strstr($str, '<shop ') !== false) {
                $data = $str;
                
                do {
                    $str   = fgets($this->handler);
                    $data .= $str;
                } while (strstr($str, '</regions_geotarget>') === false);
                //fseek($this->handler, -mb_strlen($str), SEEK_CUR);
                
                break;
            }
        }  
        return $this->_encode($data);   
    } 
    
    protected function _close_file()
    {
        if (!fclose($this->handler)) {
            throw new Model_Exception('Не удалось закрыть файл');   
        }  
        return true; 
    }
    
    protected function _cut_quotes($str)
    {
        return trim(str_replace(array('<![CDATA[', ']]>'), '', $str));    
    }
}